package com.tyut.planeGame.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.crypto.digest.MD5;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tyut.planeGame.entity.User;
import com.tyut.planeGame.entity.dto.TopUser;
import com.tyut.planeGame.entity.dto.UserDTO;
import com.tyut.planeGame.entity.form.LoginForm;
import com.tyut.planeGame.entity.form.RegisterForm;
import com.tyut.planeGame.entity.form.UpdateForm;
import com.tyut.planeGame.mapper.UserMapper;
import com.tyut.planeGame.service.UserService;
import com.tyut.planeGame.utils.UserHolder;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import static com.tyut.planeGame.utils.RedisConstants.*;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @description 针对表【user】的数据库操作Service实现
 * @createDate 2024-06-19 23:36:31
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
        implements UserService {
    @Autowired
    UserMapper userMapper;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public void register(RegisterForm registerForm) {
        User existingUser = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUsername, registerForm.getUsername()));
        if (existingUser != null) {
            throw new RuntimeException("用户名已存在");
        }
        User user = new User();
        BeanUtils.copyProperties(registerForm, user);
        user.setPassword(MD5.create().digestHex(registerForm.getPassword().getBytes()));
        userMapper.insert(user);

        //密码md5加密
    }

    @Override
    public String login(LoginForm loginForm) {

        //根据用户名查找用户
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUsername, loginForm.getUsername()));

        // 检查用户是否存在
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        //比对密码
        if (user.getPassword().equals(MD5.create().digestHex(loginForm.getPassword().getBytes()))) {
            // 5.正确，保存用户信息到redis中
            // 5.1随机生成token，作为登陆令牌
            String token = cn.hutool.core.lang.UUID.randomUUID().toString(true);
            // 5.2将User对象转为HashMap存储
            UserDTO userDTO = BeanUtil.copyProperties(user, UserDTO.class);
            // 5.3存储
            Map<String, Object> userMap = BeanUtil.beanToMap(userDTO, new HashMap<>(),
                    CopyOptions.create()
                            .setIgnoreNullValue(true)
                            .setFieldValueEditor((fieldName, fieldValue) -> fieldValue.toString()));
            String tokenKey = LOGIN_USER_KEY + token;
            stringRedisTemplate.opsForHash().putAll(tokenKey, userMap);
            // 5.4设置token有效期
            stringRedisTemplate.expire(tokenKey, LOGIN_USER_TTL, TimeUnit.MINUTES);
            // 6.返回token
            return token;
        }else{
            throw new RuntimeException("密码错误");
        }

    }
    @Override
    public String GetQuestion(String username) {
        // 根据用户名查询用户
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUsername, username));

        // 检查用户是否存在
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        // 返回用户的安全问题
        if (user.getQuestion() != null) {
            return user.getQuestion();
        } else {
            throw new RuntimeException("未找到安全问题");
        }

    }

    // 生成token的方法
    private String generateToken(User user) {
        // 使用UUID生成token（可根据需求更改生成方式）
        return UUID.randomUUID().toString();
    }

    @Override
    public void UpdatePassword(UpdateForm updateFormForm) {
        User user = userMapper.findByUsername(updateFormForm.getUsername());
        if (user.getAnswer().equals(updateFormForm.getAnswer())) {
            user.setPassword(MD5.create().digestHex(updateFormForm.getPassword().getBytes()));
            userMapper.updateById(user);
        }
        //对比当前用户问题下的答案
        //若对则修改
    }

    @Override
    public int SaveScore(int score) {
        Integer id = UserHolder.getUser().getId();
        User user = userMapper.selectById(id);
        if (user.getTopScore() == null || user.getTopScore() < score) {
            user.setTopScore(score);
        }
        userMapper.updateById(user);
        //获取最高分
        User CurrUser = userMapper.selectById(id);
        return CurrUser.getTopScore();
    }

    @Override
    public int GetScore() {
        //根据当前用户id获取score
        Integer id = UserHolder.getUser().getId();

        User user = userMapper.selectById(id);
        return user.getTopScore();
    }

    @Override
    public List<TopUser> getTopUserList() {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(User::getTopScore);

        // 查询排序后的用户列表
        List<User> users = userMapper.selectList(queryWrapper);
        List<TopUser> list = new ArrayList<>();
        for (User user : users) {
            TopUser topUser = new TopUser();
            topUser.setUsername(user.getUsername());
            topUser.setScore(String.valueOf(user.getTopScore()));
            list.add(topUser);
        }

        //根据score将user从高到低排序排序
        //返回排行榜
        return list;
    }
}
